<script lang="js">
import {defineComponent} from 'vue'
import {fetchEventSource} from "@fortaine/fetch-event-source";

export default defineComponent({
  name: "SseDemo5",
  data() {
    return {
      typedMessage: ''
    }
  },
  methods: {
    onFinish(resText) {
      this.typedMessage = resText
    },
    startListening() {
      let responseText = "";
      let remainText = "";
      let finished = false;

      // animate response to make it looks smooth
      // 通过 animateResponseText 函数逐步显示响应文本，使显示效果更平滑。
      const animateResponseText = () => {
        if (finished) {
          responseText += remainText;
          console.log("[Response Animation] finished");
          if (!responseText || responseText.length === 0) {
            // options.onError?.(new Error("empty response from server"));
          }
          return;
        }

        if (remainText.length > 0) {
          const fetchCount = Math.max(1, Math.round(remainText.length / 60));
          const fetchText = remainText.slice(0, fetchCount);
          responseText += fetchText;
          remainText = remainText.slice(fetchCount);
          this.typedMessage = responseText
        }

        requestAnimationFrame(animateResponseText);
      }

      // start animation
      animateResponseText();

      const finish = () => {
        finished = true;
        this.onFinish(responseText + remainText)
      }

      fetchEventSource("http://127.0.0.1:7777/interface", {
        onmessage: (event) => {
          if (event.data === "[DONE]" || finished) {
            return finish();
          }
          console.log('update', event.data)
          // this.typedMessage += event.data
          const chunk = event.data
          if (chunk) {
            remainText += chunk;
          }
        },
        onclose() {
          finish();
        },
      })
    },
    reset() {
      this.typedMessage = ''
    }
  },
  mounted() {
    this.startListening();
  }
})
</script>

<template>
  <div>
    <div>SseDemo5</div>
    <button @click="startListening">start</button>
    <button @click="reset">reset</button>
    <div>{{ typedMessage }}</div>
  </div>
</template>

<style scoped>

</style>
